#ifndef THREADPOOL_H
#define THREADPOOL_H

//==============================================================================
//
//    I N C L U D E S
//
//==============================================================================

#include <stdint.h>
#include <vector>
#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>

namespace tsc
{
namespace common
{

//==============================================================================
//
//    C L A S S
//
//==============================================================================

class ThreadPool : private boost::noncopyable
{
public:
  static ThreadPool* instance();

  ~ThreadPool();

  /*!
   * \brief Create an io_service object and associated it wit a thread in the pool
   * \return reference to io_service in the pool
   */
  boost::asio::io_service* add();
  /*!
   * \brief Get size of Thread pool
   * \return number of threads with associated io_services
   */
  u_int8_t getPoolSize();
  /*!
   * \brief Get io_service from the thread pool
   * \param index index in the pool
   * \return pointer to io_service
   */
  boost::asio::io_service* getIoService(u_int8_t index);
  /*!
   * \brief Start all io_services.
   */
  void startAll();

  /*!
   * \brief Stop all io_services.
   */
  void stopAll();

  void addSignal(int signal_number);

  void notifyFork(boost::asio::io_service::fork_event event);

private:
  ThreadPool();

  typedef boost::shared_ptr<boost::asio::io_service>       shpIoService_t;
  typedef boost::shared_ptr<boost::asio::io_service::work> shpWork_t;
  typedef boost::shared_ptr<boost::thread>                 shpThread_t;
  typedef boost::shared_ptr<boost::asio::signal_set>       shpSignalSet_t;

  std::vector<shpIoService_t> mIoServicePtrVec; //!< pool of io_services
  std::vector<shpWork_t>      mWorkPtrVec;      //!< work for io_services in the pool
  std::vector<shpSignalSet_t> mSignalSetPtrVec; //!< set of signals

  static ThreadPool* mpInstance;
};

} // namespace common
} // namespace tsc

#endif // THREADPOOL_H
